package com.example.security.entity.bo;

import com.example.security.entity.RoleEntity;
import com.example.security.entity.UserEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author novel
 * @date 2020/10/29
 */
public class UserDetailsImpl implements UserDetails, Serializable {

    private final UserEntity userEntity;
    private final List<RoleEntity> roleEntityList;

    public UserDetailsImpl(UserEntity userEntity, List<RoleEntity> roleEntityList) {
        this.userEntity = userEntity;
        this.roleEntityList = roleEntityList;
    }

    /**
     * 获取角色权限
     *
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> list = new ArrayList<>();
        if (this.userEntity.getRules() != null) {
            for (RoleEntity item : roleEntityList) {
                list.add(new SimpleGrantedAuthority("ROLE_" + item.getRoleName()));
            }
        }
        return list;
    }


    /**
     * 获取密码
     *
     * @return
     */
    @Override
    public String getPassword() {
        return userEntity.getPassword();
    }

    /**
     * 获取用户名
     *
     * @return
     */
    @Override
    public String getUsername() {
        return userEntity.getUserName();
    }


    /**
     * 用户账号是否过期
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }


    /**
     * 用户账号是否被锁定
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }


    /**
     * 用户密码是否过期
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }


    /**
     * 用户是否可用
     */
    @Override
    public boolean isEnabled() {
        return userEntity.isEnabled();
    }


    /**
     * 为自定义的用户类覆写 hashCode 和 equals 两个方法
     * 因为： principals 采用了以用户信息为 key 的设计
     * 在hashMap中， 以对象为key，必须覆写 hashCode 和 equals 两个方法
     * 这导致同一个用户每次登录注销时计算得到的key都不相同， 所以每次登录都会向
     * principals中添加一个用户， 而注销时却从来不能有效移除
     *
     * @return
     */
    @Override
    public int hashCode() {
        return userEntity.getUserName().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof UserDetailsImpl && this.userEntity.getUserName().equals(((UserDetailsImpl) obj).getUsername());
    }
}
